﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Little_Tower_Defense.Controller;
using Little_Tower_Defense.Interfaces;


namespace Little_Tower_Defense.Controller
{
    public class MouseController : Microsoft.Xna.Framework.GameComponent
    {

        private static MouseState oldState;
        private enum Events { Click, Release, Hover, Leave }
        private static List<IClickable> clickObjects;
        private static List<IHoverable> HoverObjects;
        private static List<IHoverable> hovered;

        static MouseController()
        {
            clickObjects = new List<IClickable>();
            HoverObjects = new List<IHoverable>();
            hovered = new List<IHoverable>();
            oldState = Mouse.GetState();
        }

        public MouseController(Game game)
            : base(game)
        {
            this.UpdateOrder = 1;
        }

        public override void Initialize()
        {

        }

        public override void Update(GameTime gameTime)
        {
            if (Game.IsActive == true)
            {
                MouseState state = Mouse.GetState();
                // Click und Release event
                if (oldState.LeftButton != state.LeftButton)
                {
                    // state hat sich verändert
                    if (state.LeftButton == ButtonState.Pressed)
                    {
                        // click
                        Dispatch(Events.Click, state);
                    }
                    else
                    {
                        // Release
                        Dispatch(Events.Release, state);
                    }
                }
                if (oldState.X == state.X && oldState.Y == state.Y)
                {
                    // Hover oder Leave status wird noch näher erforscht
                    Dispatch(Events.Hover, state);
                }
                oldState = state;
                base.Update(gameTime);
            }

        }
        /// <summary>
        /// Erfasst alle arten von Events für das sich das Objekt Registrieren kann und verknüpft diese.
        /// </summary>
        /// <param name="listener">Object das auf das Event hören soll</param>
        public static void AddListener(IMouseControl listener)
        {

            try
            {
                clickObjects.Add((IClickable)listener);
            }
            catch (Exception e)
            {

            }
            try
            {
                HoverObjects.Add((IHoverable)listener);
            }
            catch (Exception e)
            {

            }
        }

        public static void DelListener(IMouseControl listener)
        {
            try
            {
                clickObjects.Remove((IClickable)listener);
            }
            catch (Exception e)
            {

            }
            try
            {
                HoverObjects.Remove((IHoverable)listener);
            }
            catch (Exception e)
            {

            }
        }

        private static void Dispatch(Events ev, MouseState newState)
        {
            switch (ev)
            {
                case Events.Click:
                    foreach (IClickable component in clickObjects)
                    {
                        if (component.GetArea().Intersects(new Rectangle(newState.X, newState.Y, 1, 1)))
                        {
                            Little_Tower_Defense.Utilitys.Logger.WriteLog("Mouse Click", "Mouseclick Object: " + component.ToString() + " an der Position: X: " + newState.X + " Y: " + newState.Y);
                            component.Click(newState);
                        }
                    }
                    break;
                case Events.Hover:

                    for (int i = 0; i < HoverObjects.Count; i++)//IHoverable component in HoverObjects)
                    {
                        IHoverable component = HoverObjects[i];
                        if (component.GetArea().Intersects(new Rectangle(newState.X, newState.Y, 1, 1)))
                        {
                            Little_Tower_Defense.Utilitys.Logger.WriteLog("Mouse Hover", "Mousehover Object: " + component.ToString() + " an der Position: X: " + newState.X + " Y: " + newState.Y);
                            component.Hover(newState.X, newState.Y);
                        }

                    }
                    break;
                case Events.Release:
                    foreach (IClickable component in clickObjects)
                    {
                        if (component.GetArea().Intersects(new Rectangle(newState.X, newState.Y, 1, 1)))
                        {
                            Little_Tower_Defense.Utilitys.Logger.WriteLog("Mouse Released", "Mouse Object: " + component.ToString() + " an der Position: X: " + newState.X + " Y: " + newState.Y);
                            component.Release();
                        }
                    }
                    break;

            }

        }
    }
}
